package edu.buaa.resourceManager.store;

import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
import edu.buaa.resourceManager.helper.Utils;
import edu.buaa.resourceManager.vo.CustomProperty;
import edu.buaa.resourceManager.vo.ResourcePath;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Created by sjh on 17-5-21.
 */
public class JsonStore {
    private static JsonStore me;
    public final Gson json;

    public static JsonStore getInstance(){
        if(me==null){
            me = new JsonStore();
        }
        return me;
    }

    private JsonStore(){
        GsonBuilder builder = new GsonBuilder();
//        builder.registerTypeAdapter(ResourcePath.class, new ResourceFileSerializer());
//        builder.registerTypeAdapter(ResourcePath.class, new ResourceFileDeSerializer());
        this.json = builder.create();
    }

    private File getStoreFile(File file) throws IOException {
        File dir = Utils.getParentDirOfFile(file);
        return new File(dir, "README_resource-manage.json");
    }

    public void saveOrUpdate(File file, ResourcePath resourcePath) throws IOException {
        File store = getStoreFile(file);
        if(store.exists() && store.length()>0){
            try {
                List<ResourcePath> exist = this.json.fromJson(
                        new BufferedReader(new FileReader(store)),
                        new TypeToken<List<ResourcePath>>() {
                        }.getType());
                List<ResourcePath> afterMerge = merge(exist, resourcePath);
                BufferedWriter writer = new BufferedWriter(new FileWriter(getStoreFile(file)));
                writer.write(this.json.toJson(afterMerge));
                writer.close();
            }catch (Throwable e){
                e.printStackTrace();
            }
        }else{
            List<ResourcePath> list = new ArrayList<>(2);
            list.add(resourcePath);
            BufferedWriter writer = new BufferedWriter(new FileWriter(getStoreFile(file)));
            writer.write(this.json.toJson(list));
            writer.close();
        }
    }

    private List<ResourcePath> merge(List<ResourcePath> exist, ResourcePath resourcePath) {
//        boolean add=false;
//        for(int i=0; i<exist.size(); i++){
//            ResourcePath file = exist.get(i);
//            if( file.getSize()==resourcePath.getSize() &&
//                    file.getHash().equals(resourcePath.getHash())){
//                add=true;
//                exist.set(i, resourcePath);
//                break;
//            }
//        }
//
//        if(!add){
//            exist.add(resourcePath);
//        }
        return exist;
    }


//    public static class ResourceFileDeSerializer implements JsonDeserializer<ResourcePath> {
//        private Set<String> systemProperties = new HashSet<>();
//
//        public ResourceFileDeSerializer(){
//            systemProperties.add("path");
//            systemProperties.add("comment");
//            systemProperties.add("hash");
//            systemProperties.add("size");
//        }
//
//        @Override
//        public ResourcePath deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
//            ResourcePath pFile = new ResourcePath();
//            JsonObject obj = jsonElement.getAsJsonObject();
//            pFile.setComment(obj.get("comment").getAsString());
//            pFile.setPath(obj.get("path").getAsString());
////            pFile.setHash(obj.get("hash").getAsString());
////            pFile.setSize(obj.get("size").getAsLong());
//            for(Map.Entry<String,JsonElement> p:obj.entrySet()) {
//                if(!systemProperties.contains(p.getKey())){
//                    pFile.getProperties().add(new CustomProperty(p.getKey(), p.getValue().getAsString()));
//                }
//            }
//            return pFile;
//        }
//    }
//
//
//    public static class ResourceFileSerializer implements JsonSerializer<ResourcePath> {
//        @Override
//        public JsonElement serialize(ResourcePath resourcePath, Type type, JsonSerializationContext jsonSerializationContext) {
//            JsonObject jObject = new JsonObject();
//            jObject.add("comment", new JsonPrimitive(resourcePath.getComment()));
//            jObject.add("path", new JsonPrimitive(resourcePath.getPath()));
////            jObject.add("hash", new JsonPrimitive(resourcePath.getHash()));
////            jObject.add("size", new JsonPrimitive(resourcePath.getSize()));
////            jObject.add("createTime", new JsonPrimitive(resourcePath.getCreateTime().getTime()));
////            jObject.add("lastModifiedTime", new JsonPrimitive(resourcePath.getLastModifiedTime().getTime()));
//            jObject.add("metaUpdateTime", new JsonPrimitive(resourcePath.getMetaUpdateTime().getTime()));
//            jObject.add("online", new JsonPrimitive(resourcePath.isOnline()));
////            jObject.add("md5head", new JsonPrimitive(resourcePath.getHeadMd5()));
//            for(CustomProperty p: resourcePath.getProperties()){
//                jObject.add(p.getName(), new JsonPrimitive(p.getValue()));
//            }
//            return jObject;
//        }
//    }


}
